//package com.lry.sso.service.impl;
//
//import com.lry.sso.auth.common.dto.AuthConfigInfo;
//import com.lry.sso.auth.common.util.AuthUtil;
//import com.lry.sso.auth.common.util.SessionInfo;
//import com.lry.sso.auth.common.util.SessionInfoUtil;
//import com.lry.sso.common.entity.response.ResultData;
//import com.lry.sso.common.entity.response.Ret;
//import com.lry.sso.common.exception.SysErrorEnum;
//import com.lry.sso.common.exception.SysInvocationException;
//import com.lry.sso.common.util.LoginUtil;
//import com.lry.sso.data.dao.SysPermissionMapper;
//import com.lry.sso.data.dao.SysRoleMapper;
//import com.lry.sso.data.dao.SysUserMapper;
//import com.lry.sso.data.pojo.SysPermission;
//import com.lry.sso.data.pojo.SysRole;
//import com.lry.sso.data.pojo.SysUser;
//import com.lry.sso.feign.AuthFeign;
//import com.lry.sso.service.LoginService;
//import com.lry.sso.service.redis.service.RedisService;
//import com.lry.sso.service.vo.BasicUserVo;
//import com.lry.sso.service.vo.LoginParamVo;
//import com.lry.sso.service.vo.LoginResponseVo;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Service;
//import org.springframework.util.DigestUtils;
//import org.springframework.util.StringUtils;
//
//import java.util.List;
//import java.util.stream.Collectors;
//
///**
// * 登录服务接口实现
// *
// * @author 李瑞益
// * @date 2019/11/30
// */
//@Service
//public class LoginServiceImpl implements LoginService {
//
//    private static final Logger logger = LoggerFactory.getLogger(LoginServiceImpl.class);
//
//    @Autowired
//    private SysUserMapper sysUserMapper;
//
//    @Autowired
//    private SysRoleMapper sysRoleMapper;
//
//    @Autowired
//    private SysPermissionMapper sysPermissionMapper;
//
//    @Autowired
//    private CaptchaService captchaService;
//
//    @Autowired
//    private AuthFeign authFeign;
//
//    @Autowired
//    private RedisService redisService;
//
//    private AuthConfigInfo authConfigInfo;
//
//    @Override
//    public ResultData<LoginResponseVo> login(LoginParamVo param) {
//
//        authConfigInfo = authFeign.getAuthConfig();
//
////        this.validNull(param);
//        //验证码
//        //todo 暂时关闭验证码
////        if (!captchaService.validCaptcha(param.getCaptchaId(), param.getCaptcha())) {
////            throw new SysInvocationException(SsoErrorEnum.CAPTCHA_ERROR);
////        }
////        captchaService.deleteCaptcha(param.getCaptchaId());
//        this.checkLock(param.getUsername());
//        SysUser user = sysUserMapper.getByUsername(param.getUsername());
//        logger.info("登录用户：{}",param.getUsername());
//        if (user == null) {
//            throw new SysInvocationException(SsoErrorEnum.USERNAME_PASSWORD);
//        }
//        if (user.getStatus() != null && user.getStatus() == 0) {
//            throw new SysInvocationException(SsoErrorEnum.USER_DISABLE);
//        }
//        String decryptPassword = null;
//        try {
//            decryptPassword = authFeign.parsePassword(param.getPassword());
//        } catch (Exception e) {
//            logger.info("密码解密失败：{}", e.getMessage());
////            e.printStackTrace();
//            throw new SysInvocationException(SsoErrorEnum.USERNAME_PASSWORD);
//        }
//        logger.info("用户输入的密码：{}", decryptPassword);
//        if (!validPassword(decryptPassword, user.getPassword())) {
//            this.validErrorLogin(user.getUsername());
//        }
//        //登录校验通过后，清除错误登录记录
//        this.clearErrorLoginRecord(user.getUsername());
//        String msg = LoginUtil.validDegreePassword(decryptPassword);
//        //强制改密
////        if (!StringUtils.isEmpty(msg)) {
////            LoginResponseVo result = new LoginResponseVo();
////            result.setForce(true);
////            return Ret.data(result);
////        }
//        return Ret.data(getResponseBasicUser(user));
//    }
//
//    @Override
//    public LoginResponseVo getResponseBasicUser(SysUser user) {
//        String token;
//        LoginResponseVo result = new LoginResponseVo();
//        BasicUserVo userInfo = new BasicUserVo();
//
//        SessionInfo info = this.buildSessionInfo(user);
//
//        try {
//            token = authFeign.makeToken(info);
//        } catch (Exception e) {
//            logger.error("用户认证token生成失败:[{}]", e.getMessage());
//            throw new SysInvocationException(SsoErrorEnum.LOGIN_FAIL);
//        }
//        this.saveTokenToRedis(user.getUsername(), token);
//
//        userInfo.setUserId(user.getId());
//        userInfo.setUsername(user.getUsername());
//
//        result.setToken(token);
//        result.setUserInfo(userInfo);
//        return result;
//    }
//
//    @Override
//    public void logout() {
//        SessionInfo sessionInfo = SessionInfoUtil.getSessionInfo();
//        String key = AuthUtil.getLoginJwtKey(sessionInfo.getUserId());
//        String s = redisService.get(key);
//        if (!StringUtils.isEmpty(s)) {
//            //不为空则情况
//            redisService.delete(key);
//            logger.info("用户：{}，退出登录", sessionInfo.getUserName());
//        }
//    }
//
//    /**
//     * 登录成功后清除错误登录次数
//     *
//     * @param userId 用户名
//     */
//    private void clearErrorLoginRecord(String userId) {
//        logger.info("登录成功，清除错误登录记录。。。");
//        String pwdKey = AuthUtil.getLoginPwdTimesKey(userId);
//        String s = redisService.get(pwdKey);
//        if (!StringUtils.isEmpty(s)) {
//            redisService.delete(pwdKey);
//        }
//        logger.info("清除错误密码登录5次记录成功！");
//        String ipKey = AuthUtil.getLoginIpTimesKey(userId);
//        String ip = redisService.get(ipKey);
//        if (!StringUtils.isEmpty(ip)) {
//            redisService.delete(ipKey);
//        }
//        logger.info("清除错误登录30次记录成功！");
//
//    }
//
//    /**
//     * 检查 账户与IP锁定状态
//     *
//     * @param username 用户名
//     */
//    private void checkLock(String username) {
//        String ipKey = AuthUtil.getLoginIpTimesKey(username);
//        String ipValue = redisService.get(ipKey);
//        if (!StringUtils.isEmpty(ipValue)) {
//            int times = Integer.parseInt(ipValue);
//            if (times > authConfigInfo.getIpLockTimes() - 1) {
//                Long ipPttl = redisService.pttl(ipKey);
//                logger.info("同一IP时间范围内错误登录{}次，IP锁定！,锁定key：{},剩余时间：{}分钟", authConfigInfo.getIpLockTimes(), ipKey, ipPttl / 60000.0);
//                throw new SysInvocationException(SsoErrorEnum.IP_LOCK.code(), "IP被锁定");
//            }
//        }
//        String pwdKey = AuthUtil.getLoginPwdTimesKey(username);
//        String pwdValue = redisService.get(pwdKey);
//        if (!StringUtils.isEmpty(pwdValue)) {
//            int times = Integer.parseInt(pwdValue);
//            if (times > authConfigInfo.getPwdLockTimes() - 1) {
//                Long pwdPttl = redisService.pttl(pwdKey);
//                logger.info("密码输入错误{}次以上，锁定账号！,锁定key：{},剩余时间：{}分钟", authConfigInfo.getPwdLockTimes(), pwdKey, pwdPttl / 60000.0);
//                throw new SysInvocationException(SsoErrorEnum.USER_LOCK.code(), "用户已被锁定");
//            }
//        }
//    }
//
//    /**
//     * 构建需要存储的用户信息对象
//     *
//     * @param user 读取的用户信息，一定包含userId和userName
//     * @return sessioninfo对象
//     */
//    private SessionInfo buildSessionInfo(SysUser user) {
//        SessionInfo sessionInfo = new SessionInfo(user.getId(), user.getUsername());
//        List<SysRole> roleList = sysRoleMapper.listByUserId(user.getId());
//        List<Integer> roleIdList = roleList.stream().map(SysRole::getId).collect(Collectors.toList());
//        sessionInfo.setRoleIdList(roleIdList);
//        long count = roleList.stream().filter(c -> c.getId() == 1).count();
//        if (count > 0) {
//            sessionInfo.setIsAdmin(true);
//        }
//
//        List<Integer> permissionIdList = null;
//        if (roleIdList != null && roleIdList.size() > 0) {
//            List<SysPermission> permissionList = sysPermissionMapper.listByRoleId(roleIdList);
//            if (permissionList != null && permissionList.size() > 0) {
//                permissionIdList = permissionList.stream().map(SysPermission::getId).collect(Collectors.toList());
//            }
//        }
//        sessionInfo.setPermissionIdList(permissionIdList);
//        return sessionInfo;
//    }
//
//    /**
//     * 保存token到redis；并判断多点登录
//     *
//     * @param username 用户ming
//     * @param token
//     */
//    private void saveTokenToRedis(String username, String token) {
//        //存入redis 用于注销
//        String key = AuthUtil.getLoginJwtKey(username);
//        redisService.set(key, token, authConfigInfo.getLoginExpire());
//        logger.info("登录成功，存储用户信息；登录过期时间:{}秒", authConfigInfo.getLoginExpire());
//    }
//
//    /**
//     * 验证密码
//     *
//     * @param inputPassword 输入的密码
//     * @param password      数据保存的密码
//     * @return true：验证成功
//     */
//    private boolean validPassword(String inputPassword, String password) {
//        return password.equals(DigestUtils.md5DigestAsHex(inputPassword.getBytes()));
//    }
//
//    /**
//     * 验证错误登录
//     *
//     * @param username 用户名
//     */
//    private void validErrorLogin(String username) {
//        //5次锁定
//        Integer laveTimes = this.validLoginTimes(username);
//        throw new SysInvocationException(SsoErrorEnum.USERNAME_PASSWORD.code(), "用户密码输入错误，还有" + laveTimes + "机会");
//    }
//
//    /**
//     * 密码错误次数校验
//     *
//     * @param username 用户名
//     */
//    private Integer validLoginTimes(String username) {
//        String key = AuthUtil.getLoginPwdTimesKey(username);
//        String s = redisService.get(key);
//        if (!StringUtils.isEmpty(s)) {
//            int times = Integer.parseInt(s);
//            if (times > authConfigInfo.getPwdLockTimes() - 1) {
//                //超过可尝试测试；重设时间
//                logger.info("密码输入错误{}次以上，执行锁定账号！,锁定key：{}", authConfigInfo.getPwdLockTimes(), key);
//                redisService.expire(key, authConfigInfo.getPwdLock());
//
//                //ip锁定
//                this.validIpLock(username);
//                throw new SysInvocationException(SsoErrorEnum.USER_LOCK.code(), "用户已被锁定，" + authConfigInfo.getPwdLock() / 60 + "分钟后重试");
//            } else {
//                logger.info("密码输入错误，错误次数+1。。。;操作key：{}", key);
//                redisService.setrange(key, String.valueOf(times + 1));
//                //ip锁定
//                this.validIpLock(username);
//                return authConfigInfo.getPwdLockTimes() - times;
//            }
//        } else {
//            logger.info("用户登录，设置过期时间,key:{},value:{}", key, authConfigInfo.getLoginExpire());
//            redisService.set(key, String.valueOf(1), authConfigInfo.getLoginExpire());
//            this.validIpLock(username);
//            return authConfigInfo.getPwdLockTimes();
//        }
//    }
//
//    /**
//     * ip锁定判断
//     *
//     * @param username 用户名
//     * @return 剩余可操作次数
//     */
//    private Integer validIpLock(String username) {
//        String key = AuthUtil.getLoginIpTimesKey(username);
//        String s = redisService.get(key);
//        if (!StringUtils.isEmpty(s)) {
//            int times = Integer.parseInt(s);
//            if (times > authConfigInfo.getIpLockTimes() - 1) {
//                //超过可尝试测试；重设时间
//                logger.info("同一IP时间范围内错误登录{}次，执行锁定IP锁定！,锁定key：{}", authConfigInfo.getIpLockTimes(), key);
//                redisService.expire(key, authConfigInfo.getIpLock());
//                throw new SysInvocationException(SsoErrorEnum.USER_LOCK.code(), "IP被锁定，" + authConfigInfo.getIpLock() / 60 + "分钟后重试");
//            } else {
//                logger.info("错误登录，错误次数+1。。。;操作key：{}", key);
//                redisService.setrange(key, String.valueOf(times + 1));
//                return authConfigInfo.getIpLockTimes() - times;
//            }
//        } else {
//            redisService.set(key, String.valueOf(1), authConfigInfo.getLoginExpire());
//            return authConfigInfo.getIpLock();
//        }
//    }
//
//    /**
//     * 登录信息为空验证
//     *
//     * @param param 登录信息
//     * @return
//     */
//    private boolean validNull(LoginParamVo param) {
//        if (param == null) {
//            throw new SysInvocationException(SysErrorEnum.BUS_INPUT_PARAM);
//        }
//        if (StringUtils.isEmpty(param.getUsername())) {
//            throw new SysInvocationException(SsoErrorEnum.USERNAME_NULL);
//        }
//        if (StringUtils.isEmpty(param.getPassword())) {
//            throw new SysInvocationException(SsoErrorEnum.PASSWORD_NULL);
//        }
//        if (StringUtils.isEmpty(param.getCaptcha())) {
//            throw new SysInvocationException(SsoErrorEnum.CAPTCHA_NULL);
//        }
//        return true;
//    }
//}
